//
//  SKAudioPlayer.m
//  ocDemo
//
//  Created by Joggy on 16/8/4.
//  Copyright © 2016年 Joggy. All rights reserved.
//

#import "SKAudioPlayer.h"

@implementation AppDelegate (QYDelegate)

#pragma mark - 音频播放器代理
- (void)audioPlayer:(STKAudioPlayer *)audioPlayer logInfo:(NSString *)line {
    NSLog(@"SK logInfo");
    NSLog(@"%@", line);
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode {
    NSLog(@"SK unexpectedError");
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer didCancelQueuedItems:(NSArray *)queuedItems {
    NSLog(@"SK didCancelQueued");
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer didStartPlayingQueueItemId:(NSObject *)queueItemId {
    NSLog(@"SK startPlaying");
    NSDictionary *userInfo = @{@"queueItemId": queueItemId};
    [[NSNotificationCenter defaultCenter] postNotificationName:SKAudioPlayerDidStartPlayingNotification object:nil userInfo:userInfo];
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState {
    NSLog(@"SK stateChanged");
    
    NSDictionary *userInfo = @{@"previousState": [NSNumber numberWithInteger:previousState], @"state": [NSNumber numberWithInteger:state]};
    [[NSNotificationCenter defaultCenter] postNotificationName:SKAudioPlayerStateDidChangeNotification object:nil userInfo:userInfo];
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject *)queueItemId {
    NSLog(@"SK finishBuffering");
}

- (void)audioPlayer:(STKAudioPlayer *)audioPlayer didFinishPlayingQueueItemId:(NSObject *)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration {
    NSLog(@"SK didFinishPlaying");
    NSDictionary *userInfo = @{@"queueItemId": queueItemId};
    [[NSNotificationCenter defaultCenter] postNotificationName:SKAudioPlayerDidFinishPlayingNotification object:nil userInfo:userInfo];
}

@end

#pragma mark - 实现STKAudioPlayer分类
@implementation STKAudioPlayer (QYSingle)

static STKAudioPlayer *defaultPlayer = nil;

+ (STKAudioPlayer*)shareAudioPlayer {
    static dispatch_once_t token;
    dispatch_once(&token, ^{
        if(defaultPlayer == nil) {
            defaultPlayer = [[self alloc] init];
        }
    });
    return defaultPlayer;
}

@end

#pragma mark - SKAudioPlayer
@interface SKAudioPlayer() {
    
    STKAudioPlayer *player;
    UISlider *_slider;
    UILabel *_progressLabel;
    UILabel *_durationLabel;
    NSTimer *timer;
    STKAudioPlayerState playerState;
    double recordDuration;
    NSArray *allAudio;
    
}

@end

@implementation SKAudioPlayer

@dynamic playMode;

- (instancetype)init {
    self = [super init];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioPlayerDidStartPlaying:) name:SKAudioPlayerDidStartPlayingNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioPlayerStateDidChange:) name:SKAudioPlayerStateDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioPlayerDidFinishPlaying:) name:SKAudioPlayerDidFinishPlayingNotification object:nil];
    player = [STKAudioPlayer shareAudioPlayer];
    player.delegate = appDelegate;
    return self;
}

- (instancetype)initWithDelegate:(id<STKAudioPlayerDelegate>)delegate {
    self = [self init];
    player.delegate = delegate;
    return self;
}

#pragma mark - 播放器方法
- (void)play:(NSString*)urlString withAllURL:(NSArray *)allURL {
//    NSURL *url = [NSURL URLWithString:urlString];
//    STKDataSource *dataSource = [STKAudioPlayer dataSourceFromURL:url];
//    [player playDataSource:dataSource];
    [player play:urlString];
//    [player queue:@"http://7xlyw8.com1.z0.glb.clouddn.com/JayChou-QianShiQingRen.mp3"];
//    [player queue:@"http://7xlyw8.com1.z0.glb.clouddn.com/MoMingQiMiao-GuMeng.mp3"];
    allAudio = [[NSArray alloc] initWithArray:allURL];
}

- (void)play:(NSString*)path withAllPath:(NSArray *)allPath {
    NSURL *url = [NSURL fileURLWithPath:path];
    STKDataSource *dataSource = [STKAudioPlayer dataSourceFromURL:url];
    [player playDataSource:dataSource];
//    [player play:path];
    allAudio = [[NSArray alloc] initWithArray:allPath];
}

- (void)pause {
    [player pause];
}

- (void)resume {
    [player resume];
}

- (void)stop {
    [player stop];
}

- (void)seekTo:(double)value {
    [player seekToTime:value];
}

- (void)dispose {
    [player dispose];
}

- (NSString*)timeFormat:(int)time {
    int seconds = time % 60;
    int minutes = (time/60) % 60;
    return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
}

- (NSString*)timeFormatWithHour:(int)time {
    int seconds = time % 60;
    int minutes = (time/60) % 60;
    int hours = time/3600;
    return [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
}

#pragma mark 外部UI
- (void)acceptProgress:(UISlider *)slider {
    _slider = slider;
    _slider.enabled = false;
    [_slider addTarget:self action:@selector(progressSliderTouchBegin:) forControlEvents:UIControlEventTouchDown];
    [_slider addTarget:self action:@selector(progressSliderTouchEnd:) forControlEvents:UIControlEventTouchUpOutside];
    [_slider addTarget:self action:@selector(progressSliderTouchEnd:) forControlEvents:UIControlEventTouchCancel];
    [_slider addTarget:self action:@selector(progressSliderTouchEnd:) forControlEvents:UIControlEventTouchUpInside];
    [_slider addTarget:self action:@selector(progressSliderValueChange:) forControlEvents:UIControlEventValueChanged];
}

- (void)acceptProgressTimeLabel:(UILabel *)label {
    _progressLabel = label;
}

- (void)acceptDurationTimeLabel:(UILabel *)label {
    _durationLabel = label;
}

#pragma mark _slider事件

- (void)progressSliderTouchBegin:(UISlider*)slider {
    [self pauseTimer];
}

- (void)progressSliderTouchEnd:(UISlider*)slider {
    [self seekTo:slider.value];
    if(playerState == (STKAudioPlayerStatePlaying | STKAudioPlayerStateRunning)) {
        [self startTimer];
    }
}

- (void)progressSliderValueChange:(UISlider*)slider {
    if(_progressLabel) {
        _progressLabel.text = [self timeFormat:slider.value];
    }
}

#pragma mark Timer事件
- (void)startTimer {
    if(!timer) {
        __weak typeof(self) weakSelf = self;
        timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:weakSelf selector:@selector(timerEvent) userInfo:nil repeats:true];
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    }
    else {
        [timer setFireDate:[NSDate date]];
    }
}

- (void)pauseTimer {
    if(timer) {
        [timer setFireDate:[NSDate distantFuture]];
    }
}

- (void)stopTimer {
    if(timer) {
        [timer invalidate];
        timer = nil;
    }
}

- (void)timerEvent {
    if(_slider) {
        _slider.value = [self progress];
        if(_progressLabel) {
            if(recordDuration >= 3600) {
                _progressLabel.text = [self timeFormatWithHour:_slider.value];
            }
            else {
                _progressLabel.text = [self timeFormat:_slider.value];
            }
        }
    }
}

#pragma mark - getter&setter
///播放进度(seconds)
- (double)progress {
    return player.progress;
}

///播放总时长(seconds)
- (double)duration {
    return player.duration;
}

- (enum SKAudioPlayMode *)playMode {
    return self.playMode;
}

- (void)setPlayMode:(enum SKAudioPlayMode *)playMode {
    self.playMode = playMode;
}

#pragma mark - 监听事件
- (void)applicationDidEnterBackground:(NSNotification*)notification {
    NSLog(@"SK EnterBackground");
    [self pause];
}

- (void)applicationDidEnterForeground:(NSNotification*)notification {
    NSLog(@"SK EnterForeground");
    [self resume];
}

- (void)audioPlayerDidStartPlaying:(NSNotification*)notification {
    
}

- (void)audioPlayerStateDidChange:(NSNotification*)notification {
    playerState = [notification.userInfo[@"state"] integerValue];
    switch (playerState) {
        case STKAudioPlayerStatePlaying | STKAudioPlayerStateRunning:
            recordDuration = [self duration];
            if(_slider) {
                _slider.maximumValue = recordDuration;
                _slider.enabled = true;
            }
            if(_durationLabel) {
                if(recordDuration >= 3600) {
                    _durationLabel.text = [self timeFormatWithHour:[self duration]];
                }
                else {
                    _durationLabel.text = [self timeFormat:[self duration]];
                }
            }
            [self startTimer];
            break;
        case STKAudioPlayerStateBuffering | STKAudioPlayerStateRunning:
            [self pauseTimer];
            break;
        case STKAudioPlayerStatePaused | STKAudioPlayerStateRunning:
            [self pauseTimer];
            break;
        case STKAudioPlayerStateStopped:
            [self stopTimer];
            if(_slider) {
                _slider.value = 0;
                _slider.enabled = false;
            }
            if(_progressLabel) {
                _progressLabel.text = @"00:00";
            }
            if(_durationLabel) {
                _durationLabel.text = @"00:00";
            }
            break;
        default:
            break;
    }
}

- (void)audioPlayerDidFinishPlaying:(NSNotification*)notification {
    
}

#pragma mark - dealloc
- (void)dealloc {
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self stopTimer];
    _slider = nil;
    _progressLabel = nil;
    _durationLabel = nil;
    NSLog(@"dealloc");
    
}

@end
